package com.bjfu.intelligentrecognizeserver.controller;

import com.bjfu.intelligentrecognizeserver.Util.FileUtil;
import com.bjfu.intelligentrecognizeserver.Util.SessionImageStore;
import com.bjfu.intelligentrecognizeserver.pojo.entity.FileUploadInfo;
import com.bjfu.intelligentrecognizeserver.pojo.entity.UploadImageInfo;
import com.bjfu.intelligentrecognizeserver.service.UploadService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@SuppressWarnings("unused")
@RestController
@RequiredArgsConstructor
public class FileUploadController {
    private static final Logger log = LoggerFactory.getLogger(FileUploadController.class);

    private static final String UPLOAD_DIR = "C:/Users/17805/Desktop/image/";
    private final Map<String, FileUploadInfo> fileUploadMap = new ConcurrentHashMap<>();

    private final UploadService uploadService;
    @PostMapping("/uploadFileRetrofit")
    public ResponseEntity<Map<String, String>> uploadChunk(@RequestParam("file") MultipartFile file,
                                                           @RequestParam("chunkNumber") int chunkNumber,
                                                           @RequestParam("totalChunks") int totalChunks,
                                                           @RequestParam("fileName") String fileName,
                                                           @RequestParam("userId") String userId) {
        Map<String, String> response = new HashMap<>();
        log.info("userId:{} ", userId);
        log.info("fileName:{} ", fileName);

        try {
            // 创建一个唯一的文件名标识
            String uniqueFileName = UPLOAD_DIR  + fileName;
            // 初始化文件信息
            fileUploadMap.putIfAbsent(uniqueFileName, new FileUploadInfo(totalChunks));
            FileUploadInfo uploadInfo = fileUploadMap.get(uniqueFileName);

            // 保存分块文件
            File chunkFile = new File(uniqueFileName + "_" + chunkNumber);
            try (FileOutputStream fos = new FileOutputStream(chunkFile)) {
                fos.write(file.getBytes());
            }

            // 标记分块已上传
            uploadInfo.markChunkUploaded(chunkNumber);

            // 检查所有分块是否已上传完成
            if (uploadInfo.allChunksUploaded()) {
                // 合并所有分块
                File finalFile = new File(uniqueFileName);
                try (FileOutputStream fos = new FileOutputStream(finalFile, true)) {
                    for (int i = 1; i <= totalChunks; i++) {
                        File tempFile = new File(uniqueFileName + "_" + i);
                        fos.write(FileUtils.readFileToByteArray(tempFile));
                        boolean delete = tempFile.delete();
                    }
                }
                fileUploadMap.remove(uniqueFileName);
                //将上传的文件转换为Base64并存储
                String base64Image = FileUtil.imageToBase64(uniqueFileName);
                SessionImageStore.setImage(userId, base64Image);
                log.info("userid {} upload completed", userId);
            }
            //利用fileName得到上传的数据类型
            String type = fileName.split("\\.")[1];
            if (type.equals("jpg") || type.equals("jpeg") || type.equals("png")) {
                //将图片路径插入upload_image表中
                int insertImage = uploadService.insertImage(
                        new UploadImageInfo(
                                null,
                                uniqueFileName,
                                Integer.parseInt(userId),
                                1
                        )
                );
            }


            response.put("message", "Chunk uploaded successfully");
            return new ResponseEntity<>(response, HttpStatus.OK);
        } catch (IOException e) {
            log.error(e.getMessage());
            response.put("message", "Could not upload the chunk: " + e.getMessage());
            return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    @PostMapping("/uploadFile")
    public String uploadFile(@RequestParam("file") MultipartFile file,
                             @RequestParam("chunk") int chunk,
                             @RequestParam("totalChunks") int totalChunks,
                             @RequestParam("fileName") String fileName,
                             @RequestParam("fileType") String fileType) {
        log.info("fileType = {}", fileType);
        try {
            File dir = new File(UPLOAD_DIR);
            if (!dir.exists()) {
                boolean result = dir.mkdirs();
                if (result) {
                    log.info("Directory created");
                }
            }
            File outputFile = new File(dir, fileName);
            try (FileOutputStream fos = new FileOutputStream(outputFile, true)) {
                fos.write(file.getBytes());
            }

            if (chunk == totalChunks - 1) {
                return "Upload complete";
            }
            return "Chunk " + chunk + " uploaded successfully";
        } catch (IOException e) {
            log.error(e.getMessage());
            return "Failed to upload chunk " + chunk;
        }
    }

    @PostMapping("/upload-multiple")
    public ResponseEntity<String> uploadFilesWithText(
            @RequestParam("files") MultipartFile[] files,
            @RequestParam("message") String message
    ) {
        try {
            log.info("收到的消息{}", message);
            for (MultipartFile file : files) {
                String fileName = file.getOriginalFilename();
                File dest = new File(UPLOAD_DIR + File.separator + fileName);
                file.transferTo(dest);
            }
            return ResponseEntity.ok("上传成功");
        } catch (IOException e) {
            return ResponseEntity.status(500).body("上传失败");
        }

    }
}
